<?php

namespace App\Repositories;


use App\Models\Module;
use App\Models\Permission;
use App\Utils\Output;
use App\Utils\Pager;
use App\Utils\TreeUtil;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

/**
 * Class ModuleRepository
 * @package App\Repositories
 */
class ModuleRepository
{
    function AdminLis()
    {
        $lis = Module::query()->get();
        $lis = TreeUtil::toFormat($lis->toArray(), "name");
        return Output::data($lis);
    }

    function editInfo($id)
    {
        $entity = Module::find($id);
        if ($entity) {
            return Output::data($entity);
        }
        return Output::fail("数据不存在");
    }

    function lis($pid = false)
    {
        $query = Module::query();
        if ($pid !== false) {
            $query->where('pid', '=', $pid);
        }
        return $query->get();
    }

    function save($data, $id = 0)
    {
        if ($id) {
            $entity = Module::find($id);
            if (empty($entity)) {
                return Output::fail('数据不存在');
            }
        } else {
            $entity = new Module();
        }
        if (isset($data['pid'])) {
            $entity->pid = $data['pid'];
            if ($entity->pid > 0) {
                $entity->level = 2;
            } else {
                $entity->level = 1;
            }
        }
        if (isset($data['url'])) {
            $entity->url = $data['url'];
        }
        if (isset($data['hide'])) {
            $entity->hide = $data['hide'];
        }
        if (isset($data['sort'])) {
            $entity->sort = $data['sort'];
        }
        if (isset($data['name'])) {
            $entity->name = $data['name'];
        }
        if ($entity->level == 1) {
            if (isset($data['input_tag'])) {
                $entity->tag = $data['input_tag'];
            }
        } else {
            if (isset($data['tag'])) {
                $entity->tag = $data['tag'];
            }
        }
        $entity->save();
        if ($id == 0 && $entity->level == 2) {
            $actions = Arr::get($data, 'actions', []);
            if ($actions) {
                $permissions = [];
                $time = time();
                foreach ($actions['code'] as $key => $code) {
                    $permissions[] = [
                        'module_id' => $entity->id,
                        'controller' => $entity->tag,
                        'action' => $code,
                        'created_at' => $time,
                        'updated_at' => $time,
                        'name' => $actions['name'][$key],
                    ];
                }
                Permission::query()->insert($permissions);
            }
        }
        return Output::success('操作成功', $entity->id);
    }

    /**
     * 删除
     * @param $id
     * @return Output|int
     * @throws \Exception
     */
    function destroy($id)
    {
        return Module::destroy($id);
    }

    /**
     * 获取未添加的控制器
     * @return Output
     */
    public function getNotAddControllers()
    {

        $controllerNames = [];
        $base_path = app_path('Http/Controllers');
        $dirs = [
            'Admin'
        ];
        foreach ($dirs as $dir) {
            $this->_getControlers($base_path . DIRECTORY_SEPARATOR . $dir, $controllerNames, $dir . '\\');
        }
        //需要过滤的控制器
        $filterNames = [
            'Admin\Base',
            'Admin\Public',
            'Admin\Index'
        ];
        if ($controllerNames) {
            $lis = Module::query()->where('level', '=', 2)->pluck('tag')->toArray();
            foreach ($controllerNames as $key => $name) {
                if (in_array($name, $lis) || in_array($name, $filterNames)) {
                    unset($controllerNames[$key]);
                    continue;
                }
            }
        }
        return Output::success('', $controllerNames);
    }

    private function _getControlers($dir, &$lis, $qz = '')
    {
        $ls = scandir($dir);
        foreach ($ls as $item) {
            if (Str::endsWith($item, 'Controller.php')) {
                $lis[] = $qz . substr($item, 0, -strlen('Controller.php'));
            } else if (strpos($item, ".") === false) {
                $this->_getControlers($dir . DIRECTORY_SEPARATOR . $item, $lis, $qz . $item . '\\');
            }
        }
    }


    /**
     * 获取未添加的方法
     * @param string $controllerName 控制器名称
     * @return Output
     */
    public function getNotAddAction($controllerName)
    {
        $actionsNames = [];
        $this->getActions($controllerName, $actionsNames);
        if ($actionsNames) {
            $lis = Permission::query()
                ->where('controller', '=', $controllerName)
                ->pluck('action')->toArray();
            foreach ($actionsNames as $key => $name) {
                if (in_array($key, $lis)) {
                    unset($actionsNames[$key]);
                    continue;
                }
                $actionsNames[$key] = $name;
            }
        }
        return Output::success('', array_values($actionsNames));
    }

    private function getDesc($str)
    {
        $strs = explode("\n", $str);
        foreach ($strs as $s) {
            if (($pos = strpos($s, "@desc")) > 0) {
                return trim(substr($s, $pos + 5));
            }
        }
        return "";
    }

    private function getActions($name, &$lis)
    {
        $inc = resolve('\App\Http\Controllers\\' . $name . 'Controller');
        $ref = new \ReflectionClass($inc);

        $methods = $ref->getMethods(\ReflectionMethod::IS_PUBLIC);
        foreach ($methods as $method) {
            $name = $method->getName();
            //
            if ($name == 'middleware' || $name == 'getMiddleware' || $name == 'callAction' || strpos($name, "_") === 0) continue;
            $mdoc = $method->getDocComment();
            $doc = $this->getDesc($mdoc);
            if (empty($doc)) {
                if ($name == 'index' || $name == 'data') {
                    $doc = '列表';
                    $name = 'index';
                } else if ($name == 'create' || $name == 'add' || $name == 'store' || $name == 'save') {
                    $doc = '新增';
                    $name = 'create';
                } else if ($name == 'update' || $name == 'edit') {
                    $doc = '修改';
                    $name = 'edit';
                } else if ($name == 'del' || $name == 'delete' || $name == 'destroy') {
                    $doc = '删除';
                } else if ($name == 'show' || $name == 'read') {
                    $doc = '查看';
                    $name = 'show';
                } else {
                    $doc = $name;
                }
            }
            $lis[$name] = [
                'code' => $name,
                'name' => $doc
            ];
        }
    }
}

